package org.pwwong.scalautils.signals

object BindableSignal{
  def apply[T](initSig:Signal[T]) = new BindableSignal[T](initSig)
  def apply[T](initSig:T):BindableSignal[T] = apply(new ConstantSignal[T](initSig))
}

class BindableSignal[T](protected[this] var boundTo:Signal[_>:T]) extends Signal[T]{ self:BindableSignal[T] =>
  def apply():T = boundTo().asInstanceOf[T]
   
  protected def unBind { boundTo.onChange removeListener this }
  protected def bind { boundTo.onChange(this){ onChange.fire(_) } }
   
  def <=[U<:T](other:U):self.type = this<=(new ConstantSignal[T](other.asInstanceOf[T]))
  def <=[U<:T](other:Signal[U]):self.type = {
    if(other != this){
      unBind
      val prevVal = boundTo()
      boundTo = other
      bind
      if(prevVal != boundTo()) onChange.fire(boundTo())
    }
    self
  }
}
